<?php
/**
 * 
 * @author yusaint
 * @since 2014-3-9
 * @project Pfinal
 */
class Pfinal_Model_Protocol_RMDBSParser implements Pfinal_Model_Protocol_IParser{
	
	/**
	 * (non-PHPdoc)
	 * @see IProtocolParser::parse()
	 */
	public function parse(Pfinal_Model_Statement $stm){
		if ($stm instanceof Pfinal_Model_Selector){
			return $this->parseSelector($stm);
		}
		
		if ($stm instanceof Pfinal_Model_Update){
			return $this->parseUpdate($stm);
		}
		
		if ($stm instanceof Pfinal_Model_Insert){
			return $this->parseInsert($stm);
		}
		
		if ($stm instanceof Pfinal_Model_DDL){
			return $this->parseDDL($stm);
		}
		throw new Pfinal_Exception_Runtime("unknow stm");
	}
	
	protected function parseSelector(Pfinal_Model_Selector $selector){
		$protocol = new Pfinal_Model_Protocol_RMDBS();
		$protocol->setOptType(Pfinal_Model_Protocol_RMDBS::OPT_TYPE_SELECT);
		//首先解析表名
		$tableName = $selector->getTableName();
		$alias = $selector->getAlias();
		$fields = $selector->getFields();
		$protocol->setTableName($tableName,$alias);
		$joinStack = $selector->getJoinStack();
		if (!empty($joinStack)) {
			//如果join队列不为空，并且传递了别名，则sql语句中会添加别名
			if(!empty($alias)&&!empty($fields)){
				foreach ($fields as $key => $field) {
					$fields[$key] = $alias.'.'.$field;
				}
			}
			$protocol->addFields($fields);
			foreach ($joinStack as $joinSelector) {
				//首先添加查询的字段名
				$joinFields = $joinSelector->getFields();
				$joinAlais = $joinSelector->getAlias();
				if(!empty($joinAlais)&&!empty($joinFields)){
					foreach ($joinFields as $key => $joinField) {
						$joinFields[$key] = $joinAlais.'.'.$joinField;
					}
				}
				$protocol->addFields($joinFields);
				//添加join关系链
				$protocol->addJoin($joinSelector->getPre(),array($joinSelector->getTableName(),$joinSelector->getAlias()),$joinSelector->getOn());
				//添加where条件，注意，所有的where条件，在解析之前，已经添加了表名限定前缀都是形如
				//hm_user.site_id等的形式了
				$protocol->addWhere($joinSelector->getWhereCols());
				$protocol->addOrderBy($joinSelector->getOrderClause());//注意所有的orderBy和groupBy还不支持表名限定
				$protocol->addGroupBy($joinSelector->getGroupClause());
			}
		}else{
			$protocol->addFields($fields);
		}
		//添加limit order group参数
		
		$protocol->addWhere($selector->getWhereCols());
		$protocol->addOrderBy($selector->getOrderClause());//注意所有的orderBy和groupBy还不支持表名限定
		$protocol->addGroupBy($selector->getGroupClause());
		if ($selector->getOffset()>0 || $selector->getCount()>0 ){
			$protocol->limit($selector->getOffset(),$selector->getCount());//limit和count参数会优化到第一个selector上
		}
		
		return $protocol->assemble();
	}
	
	/**
	 * 
	 * @param Pfinal_Model_DDL $ddl
	 * @return string
	 */
	protected function parseDDL(Pfinal_Model_DDL $ddl){
		$protocol = new Pfinal_Model_Protocol_RMDBS();
		$protocol->setOptType(Pfinal_Model_Protocol_RMDBS::OPT_TYPE_DDL);
		$protocol->setDdlHandler($ddl->getOpt());
		$protocol->setTableName($ddl->getTableName(), $ddl->getAlias());
		return $protocol->assemble();
	}
	
	/**
	 * 
	 * @param Pfinal_Model_Insert $insert
	 * @return string
	 */
	protected function parseInsert(Pfinal_Model_Insert $insert){
		$protocol = new Pfinal_Model_Protocol_RMDBS();
		$protocol->setOptType(Pfinal_Model_Protocol_RMDBS::OPT_TYPE_INSERT);
		$protocol->setTableName($insert->getTableName(), $insert->getAlias());
		$protocol->setKSet($insert->getKSet());
		$protocol->setVSet($insert->getVSet());
		return $protocol->assemble();
	}
	
	public function parseUpdate(Pfinal_Model_Update $updater){
		$protocol = new Pfinal_Model_Protocol_RMDBS();
		$protocol->setOptType(Pfinal_Model_Protocol_RMDBS::OPT_TYPE_UPDATE);
		$protocol->setTableName($updater->getTableName(), $updater->getAlias());
		$protocol->setKSet($updater->getKSet());
		$protocol->setVSet($updater->getVSet());
		$protocol->addWhere($updater->getWhereCols());
		return $protocol->assemble();
	}
}